<?php
/**
 * Класс для работы с Mysql через расширение Mysqli.
 * Реализует шаблоны синглтона и адаптера.
 * При возникновении ошибок работы с базой генерирует
 * исключения вида DatabaseException.
 * @author Vadim Belyaev <vadimbelyaev@gmail.com>
 */
class MysqliDB
{
    /**
     * @var MysqliDB Единственный экземпляр класса
     * @static
     */
    private static $_instance = false;

    /**
     * @var Mysqli Объект для работы с Mysql
     */
    private $_mysqli;

    /**
     * Конструктор класса
     * @throws DatabaseException
     */
    private function __construct()
    {
        $config = Config::getInstance();
        $this->_mysqli = @new Mysqli($config->db_host,
                                     $config->db_user,
                                     $config->db_password,
                                     $config->db_name);
        if (mysqli_connect_errno()) {
            throw new DatabaseException(mysqli_connect_error(),
                                        mysqli_connect_errno());
        }
    }

    /**
     * Возвращает единственный экземпляр класса
     * @static
     * @return MysqliDB
     */
    public static function getInstance()
    {
        $class_name = __CLASS__;
        if (self::$_instance === false) {
            self::$_instance = new $class_name();
        }
        return self::$_instance;
    }

    /**
     * Переадресует все вызовы функций объекту Mysqli
     * @param $method_name Имя метода
     * @param $arguments Массив значений аргументов
     * @throws DatabaseException
     * @return resource
     */
    public function __call($method_name, $arguments)
    {
        $result = call_user_func_array(array($this->_mysqli, $method_name), $arguments);
        if ($this->_mysqli->errno) {
            throw new DatabaseException($this->_mysqli->error, $this->_mysqli->errno);
        }
        return $result;
    }

    /**
     * Возвращает тип значения для mysqli_stmt:bind_param
     * @param mixed $value Значение
     * @return string "i", "d" или "s" ("b" не поддерживается)
     * @see http://www.php.net/manual/ru/mysqli-stmt.bind-param.php
     */
     public static function getBindParamType($value)
     {
        if (is_int($value)) {
            return "i";
        } elseif (is_float($value)) {
            return "d";
        } else {
            return "s";
        }
     }
}
